﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using System.Security.Permissions;
using Bzure.Common.Core;

namespace Bzure.Security.Permissions.CAS
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    [Serializable]
    public abstract class CodeSecurityBaseAttribute : CodeAccessSecurityAttribute
    {
        private IDroit _droit;
        public IDroit Droit
        {
            get { return _droit; }
        }
        public string ResourceID
        {
            get { throw new NotSupportedException("this method is not ResourceID"); }
            set
            {
                if (value != null)
                {
                    _droit = new Droit(value);
                }
            }
        }
        List<IAccessCode> codes = new List<IAccessCode>();
        protected void AddAccessCode(IAccessCode accessCode)
        {
            codes.Add(accessCode);
        }
        protected void AddAccessCodeValue(int codeValue)
        {
            this.AddAccessCode(new AccessCode(codeValue));
        }
      
        public CodeSecurityBaseAttribute(SecurityAction action)
            : base(action)
        {
        }
        public override IPermission CreatePermission()
        {
            foreach (IAccessCode code in codes)
                this._droit.AddAccessCode(code);
            BzurePermission perm = null;
            if (this.Unrestricted)
                perm = new BzurePermission(PermissionState.Unrestricted);
            else
                perm = new BzurePermission(this._droit.Copy());
            return perm;
        }
        protected void SetRight<T>(T requiredRight) where T : struct
        {
            this.ResourceID = typeof(T).FullName;
            this.SetAccessCodes<T>(requiredRight);
        }
        protected void SetAccessCodes<T>(T requiredRight) where T : struct
        {
            foreach (T right in requiredRight.Parse())
            {
                this.AddAccessCodeValue(Convert.ToInt32(right));
            }
        }
    }
}
